#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "SerialSelectDialog.h"


MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , xValue(0)
{
    ui->setupUi(this);

    setWindowTitle("温湿度记录仪");

    // 创建折线系列
    seriesTemperature = new QLineSeries(this);
    seriesTemperature->setName("温度");
    seriesHumidity = new QLineSeries(this);
    seriesHumidity->setName("湿度");

    // 创建图表
    chart = new QChart();
    chart->addSeries(seriesTemperature);
    chart->addSeries(seriesHumidity);

    // 创建坐标轴
    axisX = new QValueAxis(this);
    axisY = new QValueAxis(this);
    axisX->setLabelFormat("%d");
    axisX->setTitleText("Time (s)");
    axisY->setTitleText("Value");

    // 设置坐标轴范围
    axisX->setRange(0, 10);
    axisY->setRange(0, 100);

    // 将坐标轴添加到图表
    chart->addAxis(axisX, Qt::AlignBottom);
    chart->addAxis(axisY, Qt::AlignLeft);
    seriesTemperature->attachAxis(axisX);
    seriesTemperature->attachAxis(axisY);
    seriesHumidity->attachAxis(axisX);
    seriesHumidity->attachAxis(axisY);

    // 创建图表视图并设置图表
    chartView = new QChartView(chart, this);
    chartView->setRenderHint(QPainter::Antialiasing);

    // 设置主窗口的中心部件
    setCentralWidget(chartView);

    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::updateSeries);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updateSeries()
{
    // 大于85%就更新X轴范围
    if (xValue > axisX->max() * 0.85) {
        axisX->setRange(0, xValue + 10);
    }

    // 递增X轴值
    xValue++;

    // 重绘图表
    chart->update();
}

void MainWindow::on_action_open_serial_triggered()
{
    SerialSelectDialog dlg;
    dlg.exec();
    auto ret = dlg.getSelectSerialPort();
    if (ret == std::nullopt) {
        QMessageBox::information(this, "提示", "还没有选择一个串口");
        return;
    }
    auto selectPort = ret.value();
    qDebug() << selectPort;

    QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo& port : availablePorts) {
        if (port.portName() == selectPort) {
            serialPort = new QSerialPort(port, this);
            break;
        }
    }

    // 配置串口
    serialPort->setPortName(selectPort);
    serialPort->setBaudRate(QSerialPort::Baud115200);         // 设置波特率
    serialPort->setDataBits(QSerialPort::Data8);              // 设置数据位
    serialPort->setParity(QSerialPort::NoParity);             // 设置校验位
    serialPort->setStopBits(QSerialPort::OneStop);            // 设置停止位
    serialPort->setFlowControl(QSerialPort::NoFlowControl);   // 设置流控制

    if (serialPort->open(QIODevice::ReadWrite)) {
        qInfo() << "Serial port opened successfull";
    }
    else {
        qWarning() << "Failed to open serial port";
        QMessageBox::information(this, "错误", "串口打开失败");
    }
    connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::onReadyRead);
    connect(serialPort, &QSerialPort::errorOccurred, this, &MainWindow::onErrorOccurred);

    timer->start(500);   // 设置定时器每秒触发一次
}


void MainWindow::onReadyRead()
{
    QByteArray data = serialPort->readAll();
    serialBuffer.append(data);

    if (serialBuffer.size() < 8) {
        // 剩余数据不够，下次再操作
        return;
    }

    // 将 QByteArray 转换为十六进制字符串，并用空格分隔每个字节
    QString hexString = serialBuffer.toHex().toUpper();
    QStringList hexList;
    for (int i = 0; i < hexString.length(); i += 2) {
        hexList.append(hexString.mid(i, 2));
    }

    // 用空格连接每个字节
    QString formattedHexString = hexList.join(" ");

    // 打印格式化后的字符串
    qDebug() << formattedHexString;

    // 开始查找帧头
    int pos = -1;
    for (int i = 0; i + 1 < serialBuffer.size(); i++) {
        if ((uint8_t)serialBuffer.at(i) == 0xA5 && (uint8_t)serialBuffer.at(i + 1) == 0x5A) {
            pos = i;
        }
    }
    // 如果为-1，那么全是垃圾数据
    if (pos == -1) {
        serialBuffer.clear();
        return;
    }
    else if (pos != 0) {
        // 如果不为0，那么把前面的垃圾清理掉
        serialBuffer.remove(0, pos);
    }

    if (serialBuffer.size() < 8) {
        // 一定要大于8个字节，一个数据帧
        return;
    }
    // 此时一定是A5 5A xx xx xx xx xx xx这个数据帧
    // 找到了
    // 解析数据
    uint8_t humi_int = serialBuffer.at(2);   // 湿度的整数部分
    uint8_t humi_dec = serialBuffer.at(3);   // 湿度的小数部分
    uint8_t temp_int = serialBuffer.at(4);   // 温度的整数部分
    uint8_t temp_dec = serialBuffer.at(5);   // 温度的小数部分
    // 打印数据
    qInfo("data : %02X %02X %02X %02X", humi_int, humi_dec, temp_int, temp_dec);

    double temp = (int)temp_int + (double)temp_dec / 100;
    seriesTemperature->append(xValue, temp);
    double humi = (int)humi_int + (double)humi_dec / 100;
    seriesHumidity->append(xValue, humi);

    qInfo("Temperature: %lf, Humidity: %lf", temp, humi);
}

void MainWindow::onErrorOccurred(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::ResourceError) {
        qWarning() << "Serial port error:" << serialPort->errorString();
        // 关闭串口
        serialPort->close();
        serialPort = nullptr;
        // 关闭定时器
        timer->stop();
        QMessageBox::information(this, "提示", "串口已经断开了");
    }
}


void MainWindow::on_action_close_serial_triggered()
{
    if (serialPort != nullptr) {
        if (serialPort->isOpen()) {
            serialPort->close();
        }
    }
    serialPort = nullptr;
    timer->stop();
}
